/*********************************************************************
 *
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2008, 2013, Willow Garage, Inc.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 * Author: Eitan Marder-Eppstein
 *         David V. Lu!!
 *********************************************************************/
#ifndef COSTMAP_2D_LAYERED_COSTMAP_H_
#define COSTMAP_2D_LAYERED_COSTMAP_H_

#include <costmap_2d/cost_values.h>
#include <costmap_2d/layer.h>
#include <costmap_2d/costmap_2d.h>
#include <vector>
#include <string>

namespace costmap_2d
{
class Layer;
// layered_costmap.h主要进行多个层的叠加
//实例化不同的层的插件并将它们整合为一个得分
class LayeredCostmap{
public:

  LayeredCostmap(std::string global_frame, bool rolling_window, bool track_unknown);
  ~LayeredCostmap();
  
  void updateMap(double robot_x, double robot_y, double robot_yaw);//使用新数据更新基本代价地图

  inline const std::string& getGlobalFrameID() const noexcept {
    return global_frame_;
  }

  void resizeMap(unsigned int size_x, unsigned int size_y, double resolution, double origin_x, double origin_y, bool size_locked = false);

  void getUpdatedBounds(double& minx, double& miny, double& maxx, double& maxy) {
    minx = minx_;
    miny = miny_;
    maxx = maxx_;
    maxy = maxy_;
  }

  bool isCurrent();

  Costmap2D* getCostmap() {
    return &costmap_;
  }

  bool isRolling() {
    return rolling_window_;
  }

  bool isTrackingUnknown() {
    return costmap_.getDefaultValue() == costmap_2d::NO_INFORMATION;
  }

  std::vector<boost::shared_ptr<Layer> >* getPlugins() {
    return &plugins_;
  }

  void addPlugin(boost::shared_ptr<Layer> plugin) {
    plugins_.push_back(plugin);
  }

  bool isSizeLocked() {
    return size_locked_;
  }

  void getBounds(unsigned int* x0, unsigned int* xn, unsigned int* y0, unsigned int* yn) {
    *x0 = bx0_;
    *xn = bxn_;
    *y0 = by0_;
    *yn = byn_;
  }

  bool isInitialized() {
      return initialized_;
  }
  //更新存储的Footprint，更新外接和内接圆半径，并在所有层中调用 onFootprintChanged()
  void setFootprint(const std::vector<geometry_msgs::Point>& footprint_spec);
  //返回存储的最新Footprint
  const std::vector<geometry_msgs::Point>& getFootprint() { return footprint_; }
  double getCircumscribedRadius() { return circumscribed_radius_; }
  double getInscribedRadius() { return inscribed_radius_; }

private:
  Costmap2D costmap_;         // 分层代价地图合并而成的 master grid，用于记录地图数据
  std::string global_frame_;

  bool rolling_window_;       //代价地图是否使用滚动窗口机制

  bool current_;
  double minx_, miny_, maxx_, maxy_;
  unsigned int bx0_, bxn_, by0_, byn_;

  std::vector<boost::shared_ptr<Layer> > plugins_;

  bool initialized_;
  bool size_locked_;
  double circumscribed_radius_, inscribed_radius_;
  std::vector<geometry_msgs::Point> footprint_;
};

}  // namespace costmap_2d

#endif  // COSTMAP_2D_LAYERED_COSTMAP_H_
